#ifndef SQLHELPER_HPP
#define SQLHELPER_HPP

#include <sqlite3.h>
#include <vector>
#include "log.hpp"  // 注意编译选项中需要指定日志库接口头文件路径
//#include <../third/log-system/include/interface.hpp>  // 日志系统接口头文件

namespace xzt
{
    class SqlHelper
    {
    public:
        // 参数说明：
        // void* arg: 传递给 sqlite3_exec 的第四个参数
        // int column_count: 当前结果行中的列数
        // char** column_values: 包含当前结果行中每一列的值的数组
        // char** column_names: 包含当前结果行中每一列的列名的数组
        typedef int (*SqliteCallback)(void *, int, char **, char **);

    public:
        SqlHelper(const std::string &dbfile) : _dbfile(dbfile), _handler(nullptr) {}

        // 封装sqlite3_open_v2(const char* filename, sqlite3** ppDb, int flags, const char* zVfs);
        bool open(int safe_level = SQLITE_OPEN_FULLMUTEX)
        {
            int ret = sqlite3_open_v2(_dbfile.c_str(), &_handler,
                                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | safe_level, nullptr);

            if (ret != SQLITE_OK)
            {
                LOG_ERROR("创建/打开sqlite数据库失败：%s\n", sqlite3_errmsg(_handler));
                return false;
            }
            return true;
        }

        // 封装sqlite3_exec(sqlite3*, char* sql,
        //         int(*callback)(void*, int, char**, char**),
        //         void* arg, char** err)
        // 参数arg: 传递给cb回调函数的第一个参数
        bool exec(const std::string &sql, SqliteCallback cb, void *arg)
        {
            std::unique_ptr<char[]> errmsg(new char[128]);
            char *errmsg_ptr = errmsg.get();
            int ret = sqlite3_exec(_handler, sql.c_str(), cb, arg, &errmsg_ptr);

            if (ret != SQLITE_OK)
            {
                LOG_ERROR("%s 执行语句失败, 错误信息: %s", sql.c_str(), errmsg_ptr);
                return false;
            }
            return true;
        }

        // 插入数据
        bool insert_data(const std::string &sql)
        {
            return exec(sql, nullptr, nullptr);
        }
        bool insert_data(const std::string& table_name, const std::vector<std::string>& columns, const std::vector<std::string>& values)
        {
            if(columns.size()!= values.size())
            {
                LOG_ERROR("columns和values的数量不匹配！");
                return false;
            }

            std::string sql = "INSERT INTO " + table_name + " (";
            for(int i = 0; i < columns.size(); i++)
            {
                sql += columns[i];
                if(i < columns.size() - 1)
                {
                    sql += ", ";
                }
            }
            sql += ") VALUES (";
            for(int i = 0; i < values.size(); i++)
            {
                sql += "'" + values[i] + "'";
                if(i < values.size() - 1)
                {
                    sql += ", ";
                }
            }
            sql += ");";
            return insert_data(sql);
        }

        // 删除数据
        bool delete_data(const std::string &sql)
        {
            return exec(sql, nullptr, nullptr);
        }
        bool delete_data_equal(const std::string& table_name, const std::string& column_name, const std::string& value)
        {
            std::string sql = "DELETE FROM " + table_name + " WHERE " + column_name + " = '" + value + "';";
            return delete_data(sql);
        }
        
        // 查询数据 -- callback函数用于处理查询结果
        bool query_data(const std::string &sql, SqliteCallback cb, void *arg)
        {
            // 对于查询到的每一行数据，都会调用一次回调函数cb
            return exec(sql, cb, arg);
        }


        // 封装sqlite_close_v2(sqlite3*)
        void close()
        {
            if (_handler)
            {
                sqlite3_close_v2(_handler);
            }
        }

        auto& get_handler()
        { 
            return _handler; 
        }

    protected:
        std::string _dbfile;
        sqlite3 *_handler;
    };
}



#endif // SQLHELPER_HPP